local MINOR_VERSION = tonumber(("$Revision: 68111 $"):match("%d+"))
if MINOR_VERSION > EQdkpRT.MINOR_VERSION then EQdkpRT.MINOR_VERSION = MINOR_VERSION end

local base = {bars = {}, registeredGUIDs = {}}
local math_floor = _G.math.floor
local math_min = _G.math.min
local math_max = _G.math.max

function base:OnInitialize()
	self.icon = "Interface\\Icons\\INV_Misc_QuestionMark"
	self.numColumns = 1
	self.columns = self.columns or {{}}
end

function base:OnEnable()
	if self.button then
		self.button:LockHighlight()
		self.button.enabled = true
		self.button:GetNormalTexture():SetDesaturated(false)
	end
	if EQdkpRT.activeModule then
		EQdkpRT.activeModule:Disable()
	end
	EQdkpRT:SetOption("Modules.LastActive", self:GetName())
	EQdkpRT.activeModule = self
	self:ResetBars()

	EQdkpRT.Col1:Hide()

end

function base:OnDisable()
	if self.button then
		self.button:UnlockHighlight()
		self.button.enabled = false
		self.button:GetNormalTexture():SetDesaturated(true)
	end
	EQdkpRT.activeModule = nil
	self:ReleaseBars()
end

function base:ReleaseBars()
	self:ClearBars()
	local bars = self.bars
	for i = 1, #bars do
		local v = tremove(bars)
		self.registeredGUIDs[v.guid] = nil
		v:Release()
	end
end

function base:ReleaseBar(bar)
	for k, v in ipairs(self.bars) do
		if v == bar then
			tremove(self.bars, k)
			break
		end
	end
	self.registeredGUIDs[bar.guid] = nil
	bar:Release()
	return nil
end

function base:RegisterConfigDefaults(opt)
	EQdkpRT:RegisterConfigDefaults(self:GetName(), opt)
end

function base:RegisterOptions(opt)
	EQdkpRT:RegisterOptions(self:GetName(), opt)
end

function base:AcquireBar(guid, noCreate)
	local bar = self.registeredGUIDs[guid]
	local new = false
	if not bar and not noCreate then
		bar = self:GetBar(guid)
		bar.labelPositionsUpdatedAfterResize = false
		bar.isTitle = false
		bar:SetColor(1,1,1,1)
		self.registeredGUIDs[guid] = bar
		tinsert(self.bars, bar)
		new = true
	end
	return bar, new
end

function base:GetOption(k)
	return EQdkpRT.Options[self:GetName() .. "." .. k]
end

function base:SetOption(k, v)
	EQdkpRT.Options[self:GetName() .. "." .. k] = v
end

function base:Test()
	EQdkpRT:Print("No test implemented for", self.name)
end

function base:Super(t)
	local sup = getmetatable(self)["__index"]
	return sup[t](sup == base and self or sup)
end

function base:SetTitle(t)
	EQdkpRT:SetTitle(t)
end

function base:GetBar(g)
	return EQdkpRT:GetBar(g)
end

function base:UpdateLayout()
	error("Please implement UpdateLayout in " .. tostring(self.name))
end

function base:Height()
	return (EQdkpRT.BarList:GetTop() or 0) - (EQdkpRT.BarList:GetBottom() or 0)
end

function base:Width()
	return EQdkpRT.BarList:GetRight() - EQdkpRT.BarList:GetLeft()
end

function base:Hint()
	return self.name
end

function base:ClearBars()
	EQdkpRT:ClearBars()
	self:ResetBars()
	if EQdkpRT.Options["Skin.Bars.Autocollapse"] then
		EQdkpRT.Anchor:SetHeight(EQdkpRT.Title:GetHeight() + EQdkpRT.ModuleList:GetHeight() + EQdkpRT.Options["Skin.Bars.Height"] + EQdkpRT.Options["Skin.Bars.Spacing"] + 11)
	end
end

function base:ResetBars(column)
	column = column or 1
	self.columns[column] = self.columns[column] or {}
	self.columns[column].layoutInit = false
	self.columns[column].barCount = 0
	self.columns[column].maxHeight = 0
end

function base:SetNumColumns(columns)
	local old = self.numColumns
	self.numColumns = max(1, columns)
	if self.numColumns ~= old then
		self:ReleaseBars()
	end
end

function base:InitColumn(column)
	local columnList = self.columns
	columnList[column] = columnList[column] or {}
	local columnProps = columnList[column]

	if not columnProps.layoutInit then
		self.barHeight = EQdkpRT.Options["Skin.Bars.Height"]
		self.spacing = EQdkpRT.Options["Skin.Bars.Spacing"]

		columnProps.layoutInit = true
		columnProps.offset = 7
		columnProps.totalHeight = self:Height() - columnProps.offset
		columnProps.usedHeight = 0
		columnProps.anchor = EQdkpRT.BarList
		columnProps.anchorPoint = "TOP"
		columnProps.barCount = 0
		columnProps.maxHeight = 0
	end
	return columnProps
end

function base:SetColumnSpacing(v)
	self.columnSpacing = v
end

function base:AddBar(bar, column)
	column = column or 1
	assert(column <= self.numColumns)
	local columnProps = self:InitColumn(column)
	local columnSpacing = self.columnSpacing or 0

	if self:BarSpaceLeft(column) then
		columnProps.barCount = columnProps.barCount + 1
		local barList = EQdkpRT.BarList
		local tWidth = barList:GetWidth() - 14 - (columnSpacing * (self.numColumns-1))
		local bWidth = tWidth / self.numColumns
		local left = (column - 1) * bWidth + 7 + (columnSpacing * (column - 1))
		-- EQdkpRT:Print("Setting bar width to", bWidth, "left to", left, "column", column)
		columnProps.usedHeight = columnProps.usedHeight + columnProps.offset
		bar.frame:ClearAllPoints()
		bar.frame:SetPoint("LEFT", barList, "LEFT", left, 0)
		bar.frame:SetWidth(bWidth)
		if not bar.labelPositionsUpdatedAfterResize then
			bar:UpdateLabelPositions()
			bar.labelPositionsUpdatedAfterResize = true
		end
		-- bar.frame:SetPoint("RIGHT", barList, "RIGHT", -7, 0)

		bar.frame:SetPoint("TOP", barList, "TOP", 0, columnProps.usedHeight * -1)
		columnProps.usedHeight = columnProps.usedHeight + self.barHeight + self.spacing
		if EQdkpRT.Options["Skin.Bars.Autocollapse"] then
			columnProps.maxHeight = math_max(columnProps.maxHeight, columnProps.usedHeight)
			EQdkpRT.Anchor:SetHeight(EQdkpRT.Title:GetHeight() + EQdkpRT.ModuleList:GetHeight() + columnProps.maxHeight + 4)
		end
		bar.frame:Show()
		columnProps.offset = self.spacing
		return true
	else
		return false
	end
end

function base:BarSpaceLeft(column)
	column = column or 1
	local columnProps = self:InitColumn(column)
	if EQdkpRT.Options["Skin.Bars.Autocollapse"] then
		local maxBars = EQdkpRT.Options["Skin.Bars.NumBars"]
		return columnProps.barCount <= maxBars, maxBars - columnProps.barCount
	end
	local spaceLeft = math_floor((columnProps.totalHeight - (columnProps.barCount == 0 and columnProps.offset or columnProps.usedHeight)) / (self.barHeight + self.spacing))
	return spaceLeft > 0, spaceLeft
end

EQdkpRT.ModuleBase = base
